<template>
  <div class="test-G6">
    <div id="canvas"></div>
  </div>
</template>
<script>
import G6 from "@antv/g6";
export default {
  data() {
    return {
      tree: {
        id: "cube",
        model: "cube",
        label: "销售记录表",
        children: [
          { id: "t1", model: "table", side: "left", label: "商品表" },
          { id: "t2", model: "table", side: "left", label: "门店分布表" },
          { id: "t3", model: "table", side: "left", label: "销售数据表" },
          {
            id: "c1",
            model: "category",
            label: "测试分类",
            children: [
              {
                id: "b1",
                model: "bigdata",
                label: "测试销售数据模板",
                type: "bigdata",
                children: [
                  { id: "1", model: "chart", label: "商品分类对比柱图" },
                  { id: "2", model: "chart", label: "地区销售量对比饼图" },
                ],
              },
            ],
          },
          {
            id: "r1",
            model: "report",
            label: "3月商品销售报告",
            children: [
              {
                id: "b2",
                model: "bigdata",
                label: "模板1",
                type: "bigdata",
                children: [
                  { id: "3", model: "chart", label: "商品分类对比柱图" },
                  { id: "4", model: "chart", label: "商品分类对比柱图" },
                  { id: "5", model: "chart", label: "地区销售量对比饼图" },
                ],
              },
              {
                id: "b3",
                model: "bigdata",
                label: "模板2",
                type: "bigdata",
                children: [
                  { id: "6", model: "chart", label: "商品分类对比柱图" },
                  { id: "7", model: "chart", label: "商品分类对比柱图" },
                  { id: "8", model: "chart", label: "地区销售量对比饼图" },
                ],
              },
            ],
          },
        ],
      },
    };
  },
  mounted() {
    this.draw();
  },
  methods: {
    draw() {
      const menu = new G6.Menu({
        offsetX: 6,
        offsetX: 10,
        itemTypes: ["node"],
        getContent(e) {
          return `
         <p class="menu-item" commend="edit">编辑</p>
         <p class="menu-item" commend="preview">预览</p>
         `;
        },
        handleMenuClick(target, item) {
          let commend = target.getAttribute("commend");
          let model = item.getModel();
          console.log(commend, model);
        },
        shouldBegin(evt) {
          let { model } = evt.item.getModel();
          return model == "bigdata";
        },
      });
      var graph = new G6.TreeGraph({
        container: "canvas",
        width: 1200,
        height: 800,
        pixelRatio: 2,
        modes: {
          default: [
            {
              type: "collapse-expand",
              onChange: function onChange(item, collapsed) {
                item.get("model").collapsed = collapsed;
                return true;
              },
            },
            "drag-canvas",
            "zoom-canvas",
          ],
        },
        defaultNode: {
          type: "rect",
          size: [160, 40],
          anchorPoints: [
            [0, 0.5],
            [1, 0.5],
          ],
          style: { fill: "#fff", radius: 5 },
        },
        defaultEdge: {
          type: "cubic-horizontal",
          style: { stroke: "#A3B1BF" },
        },
        layout: {
          type: "mindmap",
          direction: "H",
          getHeight: function getHeight() {
            return 16;
          },
          getWidth: function getWidth() {
            return 16;
          },
          getVGap: function getVGap() {
            return 16;
          },
          getHGap: function getHGap() {
            return 100;
          },
          getSide(node) {
            return node.data.side || "right";
          },
        },
        animateCfg: { duration: 200, easing: "linearEasing" },
        plugins: [menu],
      });

      G6.registerNode("bigdata", {
        draw(cfg, group) {
          const keyShape = group.addShape("rect", {
            attrs: {
              fill: "#8cc5ff",
              radius: 5,
              stroke: "#8cc5ff",
              width: 190,
              height: 40,
              x: -80,
              y: -20,
            },
          });
          group.addShape("image", {
            attrs: {
              width: 20,
              height: 20,
              img: require("../assets/images/link.png"),
              x: 85,
              y: -10,
            },
          });
          group.addShape("text", {
            attrs: {
              textAlign: "center",
              textBaseline: "middle",
              text: cfg.label,
              fill: "#fff",
            },
          });
          return keyShape;
        },
      });
      graph.node(function (node) {
        return {
          label: node.label.replaceAll(/(?<=^(.{10})+)/g, "\n"),
        };
      });
      this.setNodeStyle(this.tree);
      graph.data(this.tree);
      graph.render();
      graph.fitView();
    },
    setNodeStyle(node) {
      switch (node.model) {
        case "cube": {
          node.type = "circle";
          node.size = 160;
          node.style = { fill: "#409eff" };
          node.labelCfg = { style: { fontSize: 20, fill: "#ffffff" } };
          break;
        }
        case "table": {
          node.style = { fill: "#aaa", stroke: "#aaa" };
          node.labelCfg = { style: { fill: "#ffffff" } };
          break;
        }
        case "category": {
          node.style = { fill: "#fff", stroke: "#409eff" };
          break;
        }
        case "report": {
          node.style = { fill: "#fff", stroke: "#67c23a" };
          break;
        }
        case "bigdata": {
          node.style = { fill: "#8cc5ff", stroke: "#8cc5ff" };
          node.labelCfg = { style: { fontSize: 14, fill: "#ffffff" } };
          break;
        }
        case "chart": {
          node.size = [160, 30];
          node.style = { fill: "#fff", stroke: "#e6a23c" };
          break;
        }
      }
      if (node.children) {
        node.children.forEach((item) => {
          this.setNodeStyle(item);
        });
      }
    },
  },
};
</script>
<style lang="scss">
.test-G6 {
  #canvas {
    width: 1200px;
    height: 800px;
    border: 1px solid #ccc;
  }
  .g6-component-contextmenu {
    padding: 0;
  }
  .menu-item {
    margin: 0;
    padding: 5px;
    width: 60px;
    text-align: center;
    cursor: pointer;
    transition: background-color 0.2s;
    &:hover {
      background-color: #eee;
    }
  }
}
</style>